// cf-392e
// 题意：
// 给定一个长度为n(<=400)的整数序列wi(1<=wi<=10^9)。现在你可以不断的选则
// 一段连续的区间[l, r]，如果这段区间满足以下两个性质：
//   1. |w[i] - w[i+1]| = 1, 对所有(l<=i<r);
//   2. 2*w[i] - w[i+1] - w[i-1] >= 0, 对于所有的i(l<i<r)。
// 那么就可以把这段区间从原序列中删除，并且获得v[r - l + 1]的得分，
// v是初始给定的长度为n的序列（0<=|vi|<=2000）表示删除长度为i对应得分为vi。
// 现在，只要可以删除你可以不断删除，也可以随时中止这个游戏，问最大得分。
//
// 题解：
// 这题的状态真的很难想。
// 首先第二个i条件的意思是这个序列是上凸的，就是必需先递增后递减。
// 然后如果我们知道一个区间的左右端点和最大值点那么就可以算出这个区间长度。
//
// 我们可以这样dp，用f[l][r][0]表示[l, r]区间删除完的最大价值，
// f[l][r][1]表示[l, r]区间l和r同时包含在最后一次删除中且最后一次删除是单调的。
//
// 对于f[l][r][0]我们分两种情况，
//   1. 最后一次删除的序列同时包括l和r，那么我们可以枚举最大值点，
//      通过f[][][1]来算可能的最大得分；
//   2. 如果最后一次删除序列不同时包含l, r，我们就枚举划分点i，
//      然后f[l][i][0] + f[i+1][r][0]来算最大得分。
//
// 对于f[l][r][1]，假设是单调增，我们只需要枚举满足a[i] == a[l] + 1的点，
// 这是可以构成单调增的第一个可能的点，
// 然后 f[l+1][i-1][0] + f[l][r][1] + v[len] - v[len - 1]来算得分，注意要剪掉重复的。
//
// 大体就是这样，还有很多边界和细节要考虑..然后由于游戏随时可以终止，
// 取个最大值就是答案。
//
// run: $exec < input
#include <iostream>

long long const  inf = (1ll) << 44;
int const maxn = 500;
long long f[maxn][maxn][2];
bool vis[maxn][maxn][2];
long long g[maxn];
int a[maxn];
int v[maxn];
int n;

template <class T>
T abs(T x) { return x < 0 ? -x : x; }

// 0: delete [l, r]'s maximum score
// 1: l or r one is smallest and the other is bigest
long long dp(int l, int r, bool opt)
{
	long long & ret = f[l][r][opt];
	if (l > r) return ret = 0;
	if (l == r) return v[1];
	if (vis[l][r][opt]) return ret;
	vis[l][r][opt] = true;
	if (opt) {
		int delta = a[l] < a[r] ? 1 : -1;
		int len = abs(a[l] - a[r]) + 1;
		ret = -inf;
		if (a[l] == a[r] || len > r - l + 1) return ret;
		for (int i = l + 1; i <= r; i++) {
			if (a[i] == a[l] + delta)
				ret = std::max(ret, dp(l + 1, i - 1, 0) + dp(i, r, 1) - v[len - 1] + v[len]);
		}
		return ret;
	}
	ret = -inf;
	for (int i = l + 1; i < r; i++) {
		int tl = 2 * a[i] - a[l] - a[r] + 1;
		if (a[i] > a[l] && a[i] > a[r] && tl <= r - l + 1) {
			if (a[i] - a[l] + 1 > i - l + 1 || a[i] - a[r] + 1 > r - i + 1) continue;
			ret = std::max(ret, dp(l, i, 1) + dp(i, r, 1) + v[tl] - v[a[i] - a[l] + 1] - v[a[i] - a[r] + 1]);
		}
	}
	for (int i = l; i < r; i++)
		ret = std::max(ret, dp(l, i, 0) + dp(i + 1, r, 0));
	ret = std::max(ret, dp(l, r, 1));
	return ret;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n;
	for (int i = 1; i <= n; i++) std::cin >> v[i];
	for (int i = 1; i <= n; i++) std::cin >> a[i];

	for (int i = 0; i <= n; i++) {
		if (i) g[i] = std::max(g[i], g[i - 1]);
		for (int j = i + 1; j <= n; j++)
			g[j] = std::max(g[j], g[i] + dp(i + 1, j, 0));
	}
	std::cout << g[n] << '\n';
}

